package EightQueens;

/**
 * 
 * @author Sebastian Brodehl, Dennis Meyer
 *
 */

public class Algorithm {
	
	//Parameters
	private static final double mutationRate = 0.1;
	private static final double uniformRate = 0.5;
	
	public static Population evolvePopulation(Population pop)
	{
		Population newPopulation = new Population(pop.size(), false);
		newPopulation.population[0] = pop.getFittest();
		
		// Crossover population
		for (int i = 1; i < pop.size(); i++) {
			Individual in1 = selectFitIndividual(pop);
			Individual in2 = selectFitIndividual(pop);
			
			Individual newCrossoverIndi = crossOver(in1, in2);
			newPopulation.population[i] = newCrossoverIndi;
		}		
		
		// Mutate population
		for (int i = 0; i < newPopulation.size(); i++) {
			mutate(newPopulation.population[i]);
		}
		
		return newPopulation;
	}
	
	private static Individual crossOver(Individual in1, Individual in2)
	{
		Individual crossOverChild = new Individual();
		
		// Crossover
		for (int i = 0; i < in1.gene.length; i++) {
			if (i <= in1.gene.length * uniformRate)
			{
				crossOverChild.gene[i] = in1.gene[i];
			}
			else
			{
				crossOverChild.gene[i] = in2.gene[i];
			}
		}
		
		return crossOverChild;
	}
	
	private static Individual selectFitIndividual(Population pop)
	{
		Population tempPop = new Population(pop.size(), false);
		
		for (int i = 0; i < tempPop.size(); i++) {
			int randomIndex = (int) (Math.random() * pop.size());
			tempPop.population[i] = pop.population[randomIndex];
		}
		
		return tempPop.getFittest();
	}

	private static void mutate(Individual indi)
	{
		for (int i = 0; i < indi.geneLength; i++) {
			if (Math.random() <= mutationRate)
			{
				indi.gene[i] = Individual.getRandomGene();						
			}
				
		}
	}
}
